package com.pet.system.controller;

import com.pet.common.constant.ResponseCode;
import com.pet.common.model.ResponseResult;
import com.pet.system.constant.UserStatus;
import com.pet.system.domain.entity.SysResource;
import com.pet.system.domain.entity.SysUser;
import com.pet.system.domain.model.LoginUser;
import com.pet.system.domain.vo.LoginVO;
import com.pet.system.security.jwt.JwtTools;
import com.pet.system.security.jwt.SafeConfig;
import com.pet.system.security.shiro.SecurityUtils;
import com.pet.system.service.IPermissionService;
import com.pet.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * （自身）权限相关控制器 1、当前用户信息 2、当前用户权限信息
 *
 * @author Centaurea
 */
@Api(tags = "权限模块", value = "用户登录、登出、导航菜单等")
@RestController
@RequestMapping("auth")
@AllArgsConstructor
public class PermissionController {
  private final IPermissionService permissionService;
  private final ISysUserService userService;
  private final JwtTools jwtTools;
  private final SafeConfig safeConfig;

  /**
   * 普通登录入口，支持用户名、密码以及其他验证场景
   *
   * @param model xx
   * @return xx
   */
  @ApiOperation("登录")
  @PostMapping("login")
  public ResponseResult login(LoginVO model) {
    // 正则： 手机号（可走验证码）、邮箱、普通用户名, 目前先支持 普通用户名
    SysUser user = userService.getByUserName(model.getUsername());
    if (user == null) {
      return ResponseResult.error("用户名或密码错误");
    }
    if (null == user.getStatus()) {
      return ResponseResult.error("用户信息异常，请联系管理员");
    } else if (UserStatus.DISABLED.getStatus() == user.getStatus()) {
      return ResponseResult.error("用户已禁用，请联系管理员");
    } else if (UserStatus.LOCKED.getStatus() == user.getStatus()) {
      return ResponseResult.error("用户已被锁定，请稍后再尝试登录");
    }
    ByteSource credentialsSalt = ByteSource.Util.bytes(user.getSalt());
    SimpleHash simpleHash =
        new SimpleHash(
            safeConfig.getHashAlgorithmName(),
            model.getPassword(),
            credentialsSalt,
            safeConfig.getHashIterations());
    try {
      if (user.getPassword().equals(simpleHash.toString())) {
        // 成功登录, 返回用户基本信息、权限标记、菜单信息
        Map<String, Object> data = new HashMap<>(1);
        data.put(
            "jwtToken",
            jwtTools.sign(new LoginUser(user.getId(), user.getUsername(), user.getPassword())));
        return ResponseResult.success(ResponseCode.WEB_200, data);
      } else {
        return ResponseResult.error("用户名或密码错误");
      }
    } catch (Exception e) {
      e.printStackTrace();
      return ResponseResult.error(e.getMessage());
    }
  }

  @ApiOperation("退出")
  @PostMapping("logout")
  public ResponseResult logout() {
    // 考虑做黑名单, 在黑名单（即已经退出的用户）中，则验证token时，做非法处理
    SecurityUtils.logout();
    return ResponseResult.success(ResponseCode.WEB_200);
  }

  @ApiOperation("导航菜单")
  @GetMapping("nav")
  public ResponseResult nav() {
    LoginUser loginUser = SecurityUtils.getLoginUser();
    if (loginUser == null) {
      return ResponseResult.error("无权操作");
    }
    List<SysResource> sysResources = permissionService.queryResource(loginUser.getId());
    return ResponseResult.success(ResponseCode.WEB_200, sysResources);
  }
}
